﻿using Mysoft.ModelAnalysis.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using System.Xml.Serialization;
using Mysoft.ModelAnalysis.Utility;


namespace Mysoft.ModelAnalysis.Controllers
{
    public class MetadataComperController : Controller
    {
        // GET: MetadataComper
        private List<MetadataEntity> GetMetadataEntities()
        {
            FileStream fs = null;
            List <MetadataEntity> metadataEntityList=new List<MetadataEntity>();
            string path = DataSourceHelp.GetEntityMetadataPath(); //@"E:\工作\GitCode2\src\00_根目录\_metadata\Entity\";
            DirectoryInfo root = new DirectoryInfo(path);
            try
            {
                XmlSerializer xs = new XmlSerializer(typeof(MetadataEntity));
                foreach (FileInfo f in root.GetFiles())
                {
                    fs = f.OpenRead();
                    MetadataEntity metadataEntity = (MetadataEntity)xs.Deserialize(fs);
                    fs.Close();
                    if (metadataEntity.Application == "0011")
                    {
                        metadataEntityList.Add(metadataEntity);
                    }
                }
                return metadataEntityList;
            }
            catch
            {

                if (fs != null)

                    fs.Close();

                throw new Exception("Xml deserialization failed!");

            }
        }

        private List<MetadataEntity> GetCsEntities()
        {
            //string path = @"E:\工作\GitCode2\src\00_根目录\bin\Mysoft.Slxt.FinanceMng.Model.dll";
            List<MetadataEntity> metadataEntityList=new List<MetadataEntity>();
            List<string> pathList=DataSourceHelp.GetModelDlls();
            foreach (var path in pathList)
            {
                Assembly ass = Assembly.LoadFrom(path);
                List<Type> typeList = ass.GetTypes().ToList();
                typeList.RemoveAll(p => p.BaseType == null || p.BaseType.Name != "Entity");
                foreach (var type in typeList)
                {
                    MetadataEntity metadataEntity = new MetadataEntity();
                    metadataEntity.Name = type.Name;
                    if (type.CustomAttributes != null)
                    {
                        var customAttribute = type.CustomAttributes.FirstOrDefault(p => p.AttributeType.Name == "EntityNameAttribute");
                        if (customAttribute != null)
                        {
                            metadataEntity.Name = customAttribute.ConstructorArguments[0].Value.ToString();
                        }
                    }
                    
                    metadataEntity.Attributes = new Attributes();
                    metadataEntity.Attributes.MetadataAttributes = new List<MetadataAttribute>();
                    List<PropertyInfo> pis = type.GetProperties().ToList();
                    pis.RemoveAll(p => p.Name == "Attributes" || p.Name == "EntityState" || p.Name == "EntityName" || p.Name == "Item");
                    foreach (PropertyInfo pi in pis)
                    {
                        MetadataAttribute metadataAttribute = new MetadataAttribute();
                        metadataAttribute.Name = pi.Name;
                        metadataAttribute.AttributeType = pi.PropertyType.Name;
                        if (pi.CustomAttributes != null)
                        {
                            var customAttribute = pi.CustomAttributes.FirstOrDefault(p => p.AttributeType.Name == "EnumColumnAttribute");
                            if (customAttribute != null)
                            {
                                MetadataAttribute metadataAttribute2 = new MetadataAttribute();
                                if (customAttribute.ConstructorArguments.Count == 1)
                                {
                                    metadataAttribute2.Name = customAttribute.ConstructorArguments[0].Value.ToString();
                                }
                                else
                                {
                                    metadataAttribute2.Name = customAttribute.ConstructorArguments[1].Value.ToString();
                                }
                                metadataAttribute2.AttributeType = "string";
                                metadataEntity.Attributes.MetadataAttributes.Add(metadataAttribute2);
                            }
                            var customAttribute2 = pi.CustomAttributes.FirstOrDefault(p => p.AttributeType.Name == "EntityColumnAttribute");
                            if (customAttribute2 != null)
                            {
                                metadataAttribute.Name = customAttribute2.ConstructorArguments[0].Value.ToString();
                            }
                            
                        }


                        metadataEntity.Attributes.MetadataAttributes.Add(metadataAttribute);
                    }

                    metadataEntityList.Add(metadataEntity);

                }
            }
           
            return metadataEntityList;
        }

        private EntityComperResult ComperEntity(MetadataEntity csEntity, MetadataEntity metadataEntity)
        {
            EntityComperResult entityComperResult = new EntityComperResult();
            entityComperResult.Name = csEntity.Name;
            entityComperResult.IsExists = true;
            var csAttributes = csEntity.Attributes.MetadataAttributes.Select(p => p.Name.ToLower()).ToList();
            var metadataAttributes = metadataEntity.Attributes.MetadataAttributes.Select(p => p.Name.ToLower()).ToList();
            entityComperResult.EntityMoreAttribute = csAttributes.Where(p => metadataAttributes.Contains(p)==false).ToList();
            entityComperResult.MetadataMoreAttribute = metadataAttributes.Where(p => csAttributes.Contains(p) == false).ToList();
            return entityComperResult;
        }
        public List<EntityComperResult> GetEntityComperResult()
        {
            List<EntityComperResult> entityComperResultList=new List<EntityComperResult>();
            List<MetadataEntity> metadataEntities=GetMetadataEntities();
            List<MetadataEntity> csEntities = GetCsEntities();
            foreach (var csEntity in csEntities)
            {
                var metadataEntity =metadataEntities.FirstOrDefault(p => p.Name == csEntity.Name);
                if (metadataEntity == null)
                {
                    EntityComperResult entityComperResult = new EntityComperResult();
                    entityComperResult.Name = csEntity.Name;
                    entityComperResult.IsExists = false;
                    entityComperResult.MetadataMoreAttribute=new List<string>();
                    entityComperResult.EntityMoreAttribute = new List<string>();
                    entityComperResultList.Add(entityComperResult);

                }
                else
                {
                    EntityComperResult entityComperResult = ComperEntity(csEntity, metadataEntity);
                    if (entityComperResult.EntityMoreAttribute.Count > 0 ||
                        entityComperResult.MetadataMoreAttribute.Count > 0)
                    {
                        entityComperResultList.Add(entityComperResult);
                    }
                }
            }
            return entityComperResultList;
        }

        public ViewResult ComperResult()
        {
            List<EntityComperResult> entityComperResultList= GetEntityComperResult();
           

            ViewData.Model = entityComperResultList;//return View(modelClass)就是把modelClass赋值给控制器对象ViewData属性的Model属性

            return View();

        }
    }
   
}